package gsw.tool.pluggable.am;

import android.app.Activity;
import android.content.pm.ActivityInfo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 正在运行的代理Activity列表。通过缓存表管理四种启东模式的代理Activity，维护缓存池大小。
 */
public class RunningActivityList {

    private static final String TAG = RunningActivityList.class.getSimpleName();
    //所有正在运行的组件记录
    private static Map<Activity, RunningActivityRecord> mRunningActivityList = new HashMap<>();
    //启动模式为Standard的正在运行的组件记录
    private static Map<Integer, RunningActivityRecord> mRunningSingleStandardActivityList = new HashMap<>();
    //启动模式为SingleTop的正在运行的组件记录
    private static Map<Integer, RunningActivityRecord> mRunningSingleTopActivityList = new HashMap<>();
    //启动模式为SingleTask的正在运行的组件记录
    private static Map<Integer, RunningActivityRecord> mRunningSingleTaskActivityList = new HashMap<>();
    //启动模式为SingleInstance的正在运行的组件记录
    private static Map<Integer, RunningActivityRecord> mRunningSingleInstanceActivityList = new HashMap<>();
    //比较器:比较正在运行的Activity记录是否相同
    private static final Comparator<RunningActivityRecord> sRunningActivityRecordComparator = new Comparator<RunningActivityRecord>() {
        @Override
        public int compare(RunningActivityRecord lhs, RunningActivityRecord rhs) {
            if (lhs != null && rhs != null) {
                if (lhs.index > rhs.index) {
                    return 1;
                } else if (lhs.index < rhs.index) {
                    return -1;
                } else {
                    return 0;
                }
            } else if (lhs != null && rhs == null) {
                return 1;
            } else if (lhs == null && rhs != null) {
                return -1;
            } else {
                return 0;
            }
        }
    };

    /**
     * Activity创建时，把它保存到缓存中
     *
     * @param activity           代理Activity
     * @param targetActivityInfo 目标Activity的存档信息
     * @param stubActivityInfo   代理Activity的存档信息
     */
    public static void onActivtyCreate(Activity activity, ActivityInfo targetActivityInfo, ActivityInfo stubActivityInfo) {
        synchronized (mRunningActivityList) {
            //新的Activity记录放到列表的最后面，它的索引=最大索引+1
            RunningActivityRecord value = new RunningActivityRecord(activity, targetActivityInfo, stubActivityInfo, findMaxIndex() + 1);
            mRunningActivityList.put(activity, value);
            //启动模式为Standard
            if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
                mRunningSingleStandardActivityList.put(value.index, value);
            } else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
                mRunningSingleTopActivityList.put(value.index, value);
            } else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
                mRunningSingleTaskActivityList.put(value.index, value);
            } else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                mRunningSingleInstanceActivityList.put(value.index, value);
            }
        }
    }

    /**
     * Activity销毁时，把它从到缓存中移除
     *
     * @param activity 代理Activity
     */
    public static void onActivtyDestory(Activity activity) {
        synchronized (mRunningActivityList) {
            RunningActivityRecord value = mRunningActivityList.remove(activity);
            if (value != null) {
                ActivityInfo targetActivityInfo = value.targetActivityInfo;
                if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
                    mRunningSingleStandardActivityList.remove(value.index);
                } else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
                    mRunningSingleTopActivityList.remove(value.index);
                } else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
                    mRunningSingleTaskActivityList.remove(value.index);
                } else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                    mRunningSingleInstanceActivityList.remove(value.index);
                }
            }
        }
    }

    /**
     * 启动代理Activity之前，检查缓存池大小，移除已经结束运行的组件，直到缓存池大小小于最大值
     */
    public static void beforeStartActivity() {
        synchronized (mRunningActivityList) {
            for (RunningActivityRecord record : mRunningActivityList.values()) {
                if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
                    continue;
                } else if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
                    doFinshIt(mRunningSingleTopActivityList);
                } else if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
                    doFinshIt(mRunningSingleTopActivityList);
                } else if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                    doFinshIt(mRunningSingleTopActivityList);
                }
            }
        }
    }

    /**
     * 当单例组件的缓存池的大小超过5时，就移除第一个已经结束运行的代理组件，并对新的缓存列表重新排序
     *
     * @param runningActivityList 正在运行的组件列表
     */
    private static void doFinshIt(Map<Integer, RunningActivityRecord> runningActivityList) {
        if (runningActivityList != null && runningActivityList.size() >= 5) {
            List<RunningActivityRecord> activitys = new ArrayList<>(runningActivityList.size());
            activitys.addAll(runningActivityList.values());
            //根据比较器重新排序
            Collections.sort(activitys, sRunningActivityRecordComparator);
            RunningActivityRecord record = activitys.get(0);
            if (record.activity != null && !record.activity.isFinishing()) {
                record.activity.finish();
            }
        }
    }

    /**
     * 获取最大索引值，用来生成新的Activity记录的索引
     * 因为每次检查缓存表大小，移除已经结束的Activity记录时，只会按照他们的所以重新排序，不会修改他们的索引值，
     * 所以新的Activity记录的索引=最大索引值+1；
     *
     * @return mRunningActivityList缓存表的最大索引值
     */
    private static int findMaxIndex() {
        int max = 0;
        synchronized (mRunningActivityList) {
            for (RunningActivityRecord record : mRunningActivityList.values()) {
                if (max < record.index) {
                    max = record.index;
                }
            }
        }
        return max;
    }

    /**
     * 正在运行的Activity记录
     */
    private static class RunningActivityRecord {
        //正在运行的代理组件
        private final Activity activity;
        //目标组件存档信息
        private final ActivityInfo targetActivityInfo;
        //代理组件存档信息
        private final ActivityInfo stubActivityInfo;
        //在列表中的索引
        private int index = 0;

        private RunningActivityRecord(Activity activity, ActivityInfo targetActivityInfo, ActivityInfo stubActivityInfo, int index) {
            this.activity = activity;
            this.targetActivityInfo = targetActivityInfo;
            this.stubActivityInfo = stubActivityInfo;
            this.index = index;
        }
    }
}
